<?php

require_once(__DIR__ . "/../objects/WildUtils.php");

/**
 * Created by PhpStorm.
 * User: simon
 * Date: 2017/2/11
 * Time: 11:03
 */
class BaseSafeChecker
{
    private $dbId = "default";
    private $remoteHostName = "";
    const HOST_CACHE_KEY = "cached.anti.proxy.hosts";
    const IP_CACHE_KEY = "cached.anti.proxy.ips";
    private $debug = false;

    public function getHostNames()
    {
        if (MemcacheUtils::exists(AntiProxy::HOST_CACHE_KEY)) {
            return MemcacheUtils::get(AntiProxy::HOST_CACHE_KEY);
        }
        $sql = "select host from anti_proxy_hosts";
        $result = DBUtils::query_first_col($sql, $this->dbId);
        $this->debug("load host size " . count($result));
        MemcacheUtils::cache(AntiProxy::HOST_CACHE_KEY, $result, false, 12 * 60 * 60);
        return $result;
    }

    public function getIps()
    {
        if (MemcacheUtils::exists(AntiProxy::IP_CACHE_KEY)) {
            return MemcacheUtils::get(AntiProxy::IP_CACHE_KEY);
        }
        $sql = "select ip,status_id from anti_proxy_ips";
        $result = DBUtils::query_result($sql, $this->dbId);
        $this->debug("load ip size " . count($result));
        MemcacheUtils::cache(AntiProxy::IP_CACHE_KEY, $result, false, 12 * 60 * 60);
        return $result;
    }

    public function getHostName($ip)
    {
        if (1 == 2) {
            return "baiduspider-220-181-108-163.crawl.baidu.com";
        }
        if (empty($this->remoteHostName)) {
            $this->remoteHostName = gethostbyaddr($ip);
        }
        if (empty($this->remoteHostName)) {
            $this->remoteHostName = $ip;
        }
        return $this->remoteHostName;
    }

    public function openIp($ip)
    {
        $this->addIp($ip, 1);
    }

    public function blockIp($ip = "")
    {
        $ip = empty($ip) ? RequestUtils::get_remote_addr() : $ip;
        $this->addIp($ip, 2);
    }

    public function addIp($ip, $status)
    {
        $sql = "
            /**/
            insert ignore into anti_proxy_ips
            (ip,status_id,created_at)
            values
            ('$ip','$status',now())
            on duplicate key update status_id=values(status_id)
        ";
        $this->debug($sql);
        $flag = DBUtils::db_query($sql, $this->dbId);
        $this->debug($flag);
        $result = $this->getIps();
        $bean = ["ip" => $ip, "status_id" => $status];
        array_push($result, $bean);
        MemcacheUtils::cache(AntiProxy::IP_CACHE_KEY, $result, false, 12 * 60 * 60);
        return;
    }

    static public function clearCaches()
    {
        MemcacheUtils::delete(AntiProxy::IP_CACHE_KEY);
        MemcacheUtils::delete(AntiProxy::HOST_CACHE_KEY);
    }

    public function debug($string)
    {
        global $logger;
        if (!$this->debug) {
            return;
        }
        if (isset($logger)) {
            $logger->error($string);
            // return;
        }
        echo "<!-- " . date('Y-m-d H:i:s')." : " . $string . " -->";
    }

    public function isHostNameOpend($hostname)
    {
        $item = $this->findHostItem($hostname);
        return !empty($item);
    }

    public function ipOpened($ip)
    {
        $item = $this->findIpItem($ip);
        $this->debug("find ip " . json_encode($item));
        return !empty($item) && $item["status_id"] == 1;
    }

    public function ipBlocked($ip)
    {
        $item = $this->findIpItem($ip);
        return !empty($item) && $item["status_id"] == 2;
    }

    public function findIpItem($ip)
    {
        $items = $this->getIps();
        foreach ($items as $item) {
            $matched = $this->matched($ip, $item["ip"]);
            if ($matched) {
                return $item;
            }
        }
        return null;
    }

    public function findHostItem($host)
    {
        $items = $this->getHostNames();
        foreach ($items as $item) {
            if ($this->matched($host, $item)) {
                $this->debug("find ptr " . json_encode($item));
                return $item;
            }
        }
        return null;
    }


    public function matched($string, $pattern)
    {
        // $this->debug("pattern " . json_encode($pattern));
        if ($string == $pattern) {
            return true;
        }
        if (strpos("a" . $pattern, "*") == false) {
            return false;
        }
        $matcher = new WildUtils($pattern);
        return $matcher->match($string);
    }

    /**
     * @return string
     */
    public function getDbId()
    {
        return $this->dbId;
    }

    /**
     * @param string $dbId
     */
    public function setDbId($dbId)
    {
        $this->dbId = $dbId;
    }

    /**
     * @return boolean
     */
    public function isDebug()
    {
        return $this->debug;
    }

    /**
     * @param boolean $debug
     */
    public function setDebug($debug)
    {
        $this->debug = $debug;
    }


}